package cz.movie.subRenamerGUI;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import no.tornado.databinding.BindingGroup;

import org.springframework.beans.BeanUtils;

import cz.movie.subRenamer.SRConfiguration;
import cz.movie.subRenamer.SubtitleRenamer;
import cz.movie.subRenamer.SubtitleRenamerImpl;
import cz.movie.subRenamer.model.SearchingRule;

public class MainWindow extends JFrame {

	private static final long serialVersionUID = -2949287714084326130L;

	static {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private SubtitleRenamer sr = new SubtitleRenamerImpl();

	private SRConfiguration config;

	private JTextField filePath = new JTextField();
	private JTextField outputString = new JTextField();
	private JTextField defaultSubtitleLanguage = new JTextField();
	private JTextField extraPatternRule = new JTextField();
	private JTextField removeFromName = new JTextField();

	private JCheckBox extraPatternRuleReverse = new JCheckBox(Messages.getMessage("extraPatternRuleReverse"));

	private JTextPane outConsole = new JTextPane();

	private JCheckBox renameMovies = new JCheckBox(Messages.getMessage("configLabel.renameMovies"));
	private JCheckBox extract = new JCheckBox(Messages.getMessage("configLabel.extract"));
	private JCheckBox deleteEmptyDirs = new JCheckBox(Messages.getMessage("configLabel.deleteEmptyDirs"));

	private BindingGroup bindingGroup;
	private JButton browseButotnPath = new JButton(Messages.getMessage("button.browse"));
	private JButton doButton = new JButton(Messages.getMessage("button.convert"));

	private Component[] sensitive = { doButton, browseButotnPath, deleteEmptyDirs, extract, renameMovies, extraPatternRule, defaultSubtitleLanguage, outputString, filePath };

	public MainWindow(SRConfiguration configTmp) {
		if (configTmp != null) {
			this.config = configTmp;
		} else {
			config = sr.loadDefaultConfig();
		}

		setTitle("Subtitle Renamer 1.0");
		setSize(600, 600);
		doBinding();
		correctTextAreas();
		addListeners();

		JPanel mainHolder = new JPanel();
		mainHolder.setLayout(new BoxLayout(mainHolder, BoxLayout.Y_AXIS));
		getContentPane().add(mainHolder);

		mainHolder.add(createPathToFileLayout());
		mainHolder.add(createCheckBoxlayout());
		mainHolder.add(crateTextLayout());
		mainHolder.add(createExtraRuleAndExclude());
		mainHolder.add(wrapOutConsole());
		mainHolder.add(createFooterButtons());

		setDefaultCloseOperation(EXIT_ON_CLOSE);

		bindingGroup.flushModelToUI();
		centerWindow();
		new RedirecterToJTextArea(outConsole);
	}

	private void centerWindow() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Dimension dim = toolkit.getScreenSize();
		this.setLocation((int) ((dim.getWidth() / 2) - (this.getWidth() / 2)), (int) (((dim.getHeight() / 2) - (this.getHeight() / 2)) - 20));
	}

	private Component createFooterButtons() {
		JPanel holder = new JPanel();
		holder.setLayout(new GridLayout(1, 2));

		JPanel left = new JPanel(new FlowLayout(FlowLayout.LEFT));
		JPanel right = new JPanel(new FlowLayout(FlowLayout.RIGHT));

		holder.add(left);
		holder.add(right);

		// for future release
		// left.add(new JButton("dummy button"));
		// left.add(new JButton("dummy button2"));

		right.add(doButton);

		return holder;
	}

	private JPanel createPathToFileLayout() {
		JPanel panel = new JPanel();

		GroupLayout layout = new GroupLayout(panel);
		panel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		layout.setHorizontalGroup(layout.createParallelGroup().addGroup(layout.createSequentialGroup().addComponent(browseButotnPath).addComponent(filePath)));
		layout.setVerticalGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup().addComponent(browseButotnPath).addComponent(filePath)));

		panel.add(browseButotnPath);
		return panel;
	}

	private Component wrapOutConsole() {
		JScrollPane slider = new JScrollPane(outConsole);
		outConsole.setMargin(new Insets(0, 5, 0, 5));
		outConsole.setBorder(outputString.getBorder());
		slider.setAutoscrolls(true);
		slider.setPreferredSize(new Dimension(600, 6000));
		return slider;
	}

	private void correctTextAreas() {
		Font font = UIManager.getDefaults().getFont("TabbedPane.font");
		outputString.setFont(font);
		defaultSubtitleLanguage.setFont(font);
		filePath.setFont(font);
		extraPatternRule.setFont(font);
	}

	private Component createExtraRuleAndExclude() {
		JPanel configHolder = new JPanel();
		GroupLayout configLayout = new GroupLayout(configHolder);
		configLayout.setAutoCreateGaps(true);
		configLayout.setAutoCreateContainerGaps(true);
		configHolder.setLayout(configLayout);

		JLabel extraPatternRuleLabel = new JLabel(Messages.getMessage("extraPatternRuleLabel"));
		JLabel removeFromNameLabel = new JLabel(Messages.getMessage("removeFromName"));
		SequentialGroup extraRule = configLayout.createSequentialGroup().addComponent(extraPatternRule).addComponent(extraPatternRuleReverse);

		SequentialGroup horizontal = configLayout.createSequentialGroup();
		horizontal.addGroup(configLayout.createParallelGroup().addComponent(extraPatternRuleLabel).addComponent(removeFromNameLabel));
		horizontal.addGroup(configLayout.createParallelGroup().addGroup(extraRule).addComponent(removeFromName));

		SequentialGroup vertical = configLayout.createSequentialGroup();
		vertical.addGroup(configLayout.createParallelGroup().addComponent(extraPatternRuleLabel).addComponent(extraPatternRule).addComponent(extraPatternRuleReverse));
		vertical.addGroup(configLayout.createParallelGroup().addComponent(removeFromNameLabel).addComponent(removeFromName));

		configLayout.setHorizontalGroup(horizontal);
		configLayout.setVerticalGroup(vertical);

		return configHolder;

	}

	private Component crateTextLayout() {
		JPanel configHolder = new JPanel();
		GroupLayout configLayout = new GroupLayout(configHolder);
		configLayout.setAutoCreateGaps(true);
		configLayout.setAutoCreateContainerGaps(true);
		configHolder.setLayout(configLayout);

		JLabel outputStringLabel = new JLabel(Messages.getMessage("configLabel.outputString"));
		JLabel defaultSubLanguageLabel = new JLabel(Messages.getMessage("configLabel.defaultSubtitleLanguage"));

		SequentialGroup horizontal = configLayout.createSequentialGroup();
		horizontal.addGroup(configLayout.createParallelGroup().addComponent(outputStringLabel).addComponent(defaultSubLanguageLabel));
		horizontal.addGroup(configLayout.createParallelGroup().addComponent(outputString).addComponent(defaultSubtitleLanguage));

		SequentialGroup vertical = configLayout.createSequentialGroup();
		vertical.addGroup(configLayout.createParallelGroup().addComponent(outputStringLabel).addComponent(outputString));
		vertical.addGroup(configLayout.createParallelGroup().addComponent(defaultSubLanguageLabel).addComponent(defaultSubtitleLanguage));

		configLayout.setHorizontalGroup(horizontal);
		configLayout.setVerticalGroup(vertical);

		return configHolder;
	}

	private JPanel createCheckBoxlayout() {
		JPanel checkPanel = new JPanel(new FlowLayout());
		checkPanel.add(renameMovies);
		checkPanel.add(extract);
		checkPanel.add(deleteEmptyDirs);
		return checkPanel;
	}

	private void doBinding() {
		bindingGroup = new BindingGroup(config);
		bindingGroup.add(outputString, "outputString");
		bindingGroup.add(defaultSubtitleLanguage, "defaultSubtitleLanguage");
		bindingGroup.add(renameMovies, "renameMovies");
		bindingGroup.add(extract, "extract");
		bindingGroup.add(deleteEmptyDirs, "deleteEmptyDirs");
		bindingGroup.add(removeFromName, "removeFromName");
		bindingGroup.bind();
	}

	private void addListeners() {
		renameMovies.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				outputString.setEnabled(renameMovies.isSelected());
			}
		});

		browseButotnPath.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				final JFileChooser fc = new JFileChooser();
				fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				if (fc.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
					File file = fc.getSelectedFile();
					filePath.setText(file.getAbsolutePath());
				}
			}
		});

		doButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				enableAll(false);
				Thread thread = new Thread(new Runnable() {

					public void run() {
						try {
							bindingGroup.flushUIToModel();
							SRConfiguration config = LoadConfig();
							SubtitleRenamer worker = new SubtitleRenamerImpl();
							worker.process(new File(filePath.getText()).getAbsolutePath(), config);
						} finally {
							enableAll(true);
						}

					}

					private SRConfiguration LoadConfig() {

						SRConfiguration srConfiguration = new SRConfiguration();
						BeanUtils.copyProperties(config, srConfiguration, new String[] { "rules" });
						ArrayList<SearchingRule> rules = new ArrayList<SearchingRule>();
						rules.addAll(config.getRules());
						srConfiguration.setRules(rules);
						if (!extraPatternRule.getText().trim().isEmpty()) {
							SearchingRule extraRule = new SearchingRule();
							extraRule.setReverseOrder(extraPatternRuleReverse.isSelected());
							extraRule.createPattern(extraPatternRule.getText());
							srConfiguration.getRules().add(extraRule);
						}
						return srConfiguration;
					}
				});
				thread.start();

			}
		});
	}

	public void enableAll(boolean b) {
		for (Component c : sensitive) {
			c.setEnabled(b);
		}
	}

}
